Skip to content

fix(runtime): drop the runnables manually, and forget them on other threads#493

Closed
Berrysoft wants to merge 1 commit into
compio-rs:masterfrom
Berrysoft:fix/runtime-drop
Closed

fix(runtime): drop the runnables manually, and forget them on other threads#493
Berrysoft wants to merge 1 commit into
compio-rs:masterfrom
Berrysoft:fix/runtime-drop

Conversation

@Berrysoft
Copy link
Copy Markdown
Member

cc: @Paraworker

The timer runtime is cleared before the scheduler, to drop the remaining wakers. All runnables are dropped in the context of current runtime.

The runnable will be forgotten, if the runtime has been dropped, and the waker is waked on another thread.

@Berrysoft Berrysoft self-assigned this Oct 27, 2025
@Berrysoft Berrysoft added bug Something isn't working package: runtime Related to compio-runtime labels Oct 27, 2025
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR addresses runtime cleanup issues by implementing proper resource management during Runtime shutdown. The changes ensure that runnables (async tasks) are safely dropped in the correct thread context, and implements a mechanism to forget runnables that are woken on other threads after the runtime has been destroyed.

Key changes:

  • Added a Drop implementation for Runtime that clears timer runtime before scheduler cleanup
  • Implemented thread-safety checks to prevent unsafe cross-thread runnable drops
  • Added a test case to verify proper cleanup of detached spawned tasks

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
compio-runtime/tests/drop.rs New test verifying runtime cleanup with detached spawned tasks
compio-runtime/src/runtime/time.rs Added clear() method to TimerRuntime for cleanup
compio-runtime/src/runtime/scheduler/mod.rs Implemented thread-safety check and clear() method for scheduler cleanup
compio-runtime/src/runtime/mod.rs Added Drop implementation to orchestrate cleanup of timer runtime and scheduler

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if let Some(task_queue) = task_queue.upgrade() {
task_queue.push(runnable, &notify);
} else if thread_guard.get().is_none() {
// It's not safe to drop the runnable in another thread.
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should explain why it's not safe to drop the runnable in another thread, and clarify that the condition thread_guard.get().is_none() means we're on a different thread. Consider expanding: 'If we're on a different thread (thread_guard.get().is_none()) and the task queue has been dropped, we cannot safely drop the runnable because [reason], so we forget it to prevent the drop from running.'

Suggested change
// It's not safe to drop the runnable in another thread.
// If we're on a different thread (thread_guard.get().is_none()) and the task queue has been dropped,
// we cannot safely drop the runnable because its destructor may access thread-local or queue-related resources
// that are only valid on the original thread. Dropping it here could lead to undefined behavior.
// Therefore, we use std::mem::forget to prevent the destructor from running.

Copilot uses AI. Check for mistakes.
Comment on lines +163 to +174
pub(crate) fn clear(&self) {
loop {
// SAFETY:
// `Scheduler` is `!Send` and `!Sync`, so this method is only called
// on `TaskQueue`'s creator thread.
let tasks = unsafe { self.task_queue.pop() };

if let (None, None) = tasks {
break;
}
}
}
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clear() method pops tasks but doesn't explicitly drop them or handle them in any way. While Rust will drop the returned tasks automatically when they go out of scope at the end of each loop iteration, this implicit behavior should be documented to clarify that the purpose is to drop all pending tasks. Consider adding a comment explaining this or explicitly binding and dropping: let _tasks = unsafe { self.task_queue.pop() }; // Drop all pending tasks.

Copilot uses AI. Check for mistakes.
@Paraworker
Copy link
Copy Markdown
Contributor

I think I’ve figured out how async-executor handles it. I can make a PR to replace this one.

@Berrysoft
Copy link
Copy Markdown
Member Author

Great! Go ahead please.

@Berrysoft
Copy link
Copy Markdown
Member Author

Closed in favor of #494

@Berrysoft Berrysoft closed this Oct 28, 2025
@Berrysoft Berrysoft deleted the fix/runtime-drop branch November 3, 2025 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working package: runtime Related to compio-runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants